package com.tcm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tcm.entity.*;
import com.tcm.entity.dto.param.LeaderUpdateParam;
import com.tcm.entity.vo.LeaderListResult;
import com.tcm.exception.DatabaseOperationException;
import com.tcm.exception.EntityInvalidException;
import com.tcm.mapper.LeaderMapper;
import com.tcm.mapper.RoleUserMapper;
import com.tcm.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 课程组组长业务实现类
 * @author Guqier
 * @version 1.0
 * @date 2023/7/18 16:23
 */
@Service
public class LeaderServiceImpl extends ServiceImpl<LeaderMapper, Leader> implements LeaderService {

    @Autowired
    private TeacherService teacherService;

    @Autowired
    private TermService termService;

    @Autowired
    private BookService bookService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private UserService userService;

    @Autowired
    private RoleUserMapper roleUserMapper;

    private static final String LEADER_ROLE_KEY = "leader";// 课程组组长角色码

    public static final int COURSE_TYPE = 0;// book表课程类型为0

    /**
     * 新增课程组组长关系
     * @param param 课程组组长关系更新参数
     * @param currUserId 当前登录用户ID
     * @return 处理结果，true为成功
     * @throws DatabaseOperationException 数据库操作异常
     */
    @Override
    @Transactional
    public boolean addLeaderRelationship(LeaderUpdateParam param, Long currUserId) throws DatabaseOperationException{
        // 校验数据是否已存在
        LambdaQueryWrapper<Leader> leaderLambdaQueryWrapper = new LambdaQueryWrapper<>();
        leaderLambdaQueryWrapper.eq(Leader::getTeacherId, param.getTeacherId());
        leaderLambdaQueryWrapper.eq(Leader::getTermId, param.getTermId());
        leaderLambdaQueryWrapper.eq(Leader::getBookId, param.getBookId());
        if (this.count(leaderLambdaQueryWrapper) != 0) {
            throw new DatabaseOperationException("数据已存在");
        }
        // 校验数据正确性
        Teacher teacher = teacherService.getById(param.getTeacherId());
        Term term = termService.getById(param.getTermId());
        Book book = bookService.getById(param.getBookId());
        if (teacher == null || term == null || book == null){
            return false;
        }
        if (!book.getType().equals(COURSE_TYPE)){
            return false;
        }
        // 保存课程组组长关系
        Leader leader = new Leader();
        leader.setTeacherId(teacher.getId());
        leader.setTermId(term.getId());
        leader.setBookId(book.getId());
        leader.setCreateUser(currUserId);
        leader.setUpdateUser(currUserId);
        boolean saveLeader = this.save(leader);

        // 保存角色关系
        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Role::getRoleKey, LEADER_ROLE_KEY);
        Role role = roleService.getOne(queryWrapper);
        User user = userService.getUserByAccount(teacher.getAccount());
        RoleUser roleUser = new RoleUser();
        roleUser.setRoleId(role.getId());
        roleUser.setUserId(user.getId());
        roleUser.setCreateUser(currUserId);
        roleUser.setUpdateUser(currUserId);
        int insert = roleUserMapper.insert(roleUser);
        if (!saveLeader || insert != 1){
            throw new DatabaseOperationException("数据库操作失败");
        }
        return true;
    }

    /**
     * 删除课程组组长关系
     * @param id 课程组组长关系ID
     * @param currUserId 当前登录用户ID
     * @return 删除结果，true为成功
     */
    @Override
    @Transactional
    public boolean removeLeaderRelationship(Long id, Long currUserId){
        Leader leader = this.getById(id);
        if (leader == null) {
            return false;
        }
        // 删除课程组组长关系
        leader.setUpdateUser(currUserId);
        boolean removeLeader = this.updateById(leader) && this.removeById(id);

        // 获取用户、角色实体
        Teacher teacher = teacherService.getById(leader.getTeacherId());
        User user = userService.getUserByAccount(teacher.getAccount());// 获取用户
        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Role::getRoleKey, LEADER_ROLE_KEY);
        Role role = roleService.getOne(queryWrapper);// 获取角色
        if (user == null || role == null){
            throw new EntityInvalidException("用户或角色不存在");
        }

        if (!removeLeader){
            throw new DatabaseOperationException("数据库操作失败");
        }
        return true;
    }

    /**
     * 修改课程组组长关系
     * @param param 更新数据封装类
     * @param currUserId 当前用户ID
     * @return 处理结果，true为成功
     */
    @Override
    @Transactional
    public boolean modifyLeaderRelationship(LeaderUpdateParam param, Long currUserId){
        // 校验数据正确性
        Leader leader = this.getById(param.getId());
        if (leader == null) {
            return false;
        }
        Teacher teacher = teacherService.getById(param.getTeacherId());
        if (teacher == null){
            return false;
        }
        // 更新角色关系
        User user = userService.getUserByAccount(teacher.getAccount());// 获取原有角色
        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Role::getRoleKey, LEADER_ROLE_KEY);
        Role role = roleService.getOne(queryWrapper);// 获取角色
        LambdaQueryWrapper<RoleUser> roleUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
        roleUserLambdaQueryWrapper.eq(RoleUser::getUserId, user.getId());
        roleUserLambdaQueryWrapper.eq(RoleUser::getRoleId, role.getId());
        RoleUser roleUser = roleUserMapper.selectOne(roleUserLambdaQueryWrapper);
        if (roleUser == null) {
            RoleUser newRoleUser = new RoleUser();
            newRoleUser.setRoleId(role.getId());
            newRoleUser.setUserId(user.getId());
            newRoleUser.setCreateUser(currUserId);
            newRoleUser.setUpdateUser(currUserId);
            if (roleUserMapper.insert(newRoleUser) != 1) {
                throw new DatabaseOperationException("角色关系插入失败");
            }
        }
        // 更新实体
        leader.setTeacherId(teacher.getId());
        leader.setUpdateUser(currUserId);
        boolean leaderUpdate = this.updateById(leader);

        if (!leaderUpdate){
            throw new DatabaseOperationException("数据库更新失败");
        }
        return true;
    }

    /**
     * 获取课程组组长关系列表
     * @param termId 学期ID
     * @return 课程组组长关系列表
     */
    @Override
    public List<LeaderListResult> getLeaderRelationshipList(Long termId){
        // 查询指定学期课程组组长
        LambdaQueryWrapper<Leader> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Leader::getTermId, termId);
        List<Leader> leaders = this.list(queryWrapper);
        // 准备数据
        List<Teacher> teachers = teacherService.list();
        List<Term> terms = termService.list();
        List<Book> courses = bookService.getBookList().stream().filter(book -> book.getType().equals(COURSE_TYPE)).collect(Collectors.toList());
        return leaders.stream().map(leader -> {
            LeaderListResult leaderListResult = new LeaderListResult();
            BeanUtils.copyProperties(leader, leaderListResult);
            teachers.stream().filter(teacher -> teacher.getId().equals(leader.getTeacherId())).findFirst().ifPresent(teacher -> leaderListResult.setTeacherName(teacher.getName()));
            terms.stream().filter(term -> term.getId().equals(leader.getTermId())).findFirst().ifPresent(term -> leaderListResult.setTermName(term.getName()));
            courses.stream().filter(course -> course.getId().equals(leader.getBookId())).findFirst().ifPresent(course -> leaderListResult.setBookName(course.getName()));
            return leaderListResult;
        }).collect(Collectors.toList());
    }

}
